package com.it.App.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

@Data
@Component
@ConfigurationProperties(prefix = "coke.jwt")
public class JwtUtils {
	// JWT 过期时间（单位：秒）
	private long expire;
	
	// JWT 密钥，用于签名和验证
	private String secret;
	
	// JWT 头部字段，可自定义
	private String header;
	
	/**
	 * 生成 JWT
	 *
	 * @param username 用户名
	 * @return JWT 字符串
	 */
	public String generateToken(String username) {
		// 获取当前时间
		Date nowDate = new Date();
		
		// 计算过期时间，当前时间 + 过期时长
		Date expireDate = new Date(nowDate.getTime() + expire);
		
		// 使用 JWT Builder 构建 JWT
		return Jwts.builder()
			.setHeaderParam("typ", "JWT") // 设置头部信息，通常为JWT
			.setSubject(username) // 设置主题，通常为用户名
			.setIssuedAt(nowDate) // 设置签发时间，即当前时间
			.setExpiration(expireDate) // 设置过期时间
			.signWith(SignatureAlgorithm.HS512, secret) // 使用HS512签名算法和密钥进行签名
			.compact();
	}
	
	/**
	 * 解析 JWT 获取声明
	 *
	 * @param jwt JWT 字符串
	 * @return JWT 中的声明部分
	 */
	public Claims getClaimByToken(String jwt) {
		try {
			// 使用 JWT 解析器解析 JWT，并获取声明部分
			return Jwts.parser()
				.setSigningKey(secret) // 设置解析时的密钥，必须与生成时的密钥一致
				.parseClaimsJws(jwt)
				.getBody();
		} catch (Exception e) {
			// 解析失败，返回null
			return null;
		}
	}
	
	/**
	 * 检查 JWT 是否过期
	 *
	 * @param claims JWT 中的声明部分
	 * @return 是否过期
	 */
	public boolean isTokenExpired(Claims claims) {
		// 检查过期时间是否在当前时间之前
		return claims.getExpiration().before(new Date());
	}

}
